package com.jason.fingerprint.ui;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.kymjs.aframe.database.DbModel;
import org.kymjs.aframe.database.KJDB;
import org.kymjs.aframe.utils.StringUtils;

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.fpi.MtRfid;
import android.media.AudioManager;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.Toast;
import android_serialport_api.FingerprintManager;

import com.jason.fingerprint.AppContext;
import com.jason.fingerprint.R;
import com.jason.fingerprint.adapter.PictureGridAdapter;
import com.jason.fingerprint.adapter.SignInRecordAdapter;
import com.jason.fingerprint.beans.SignInRecordBean;
import com.jason.fingerprint.beans.SponsorInfo;
import com.jason.fingerprint.beans.ui.FingerPrintBean;
import com.jason.fingerprint.beans.ui.ImageOrAudioBean;
import com.jason.fingerprint.common.DataHelper;
import com.jason.fingerprint.common.DateFormat;
import com.jason.fingerprint.common.RemainingTimeCalculator;
import com.jason.fingerprint.common.SoundRecorder;
import com.jason.fingerprint.common.SoundRecorder.OnStateChangedListener;
import com.jason.fingerprint.common.UIHelper;
import com.jason.fingerprint.configs.DataConfig;
import com.jason.fingerprint.logic.MatchFingerprintSyncLogic;
import com.jason.fingerprint.logic.SignInUploadLogic;
import com.jason.fingerprint.logic.UploadToTempSyncLogic;
import com.jason.fingerprint.service.SoundRecorderService;
import com.jason.fingerprint.service.SoundRecorderService.SoundRecorderBinder;
import com.jason.fingerprint.service.SoundRecorderService.StopRecordCallback;
import com.jason.fingerprint.utils.DataUtils;
import com.jason.fingerprint.widget.ExpandListView;
import com.jason.fingerprint.widget.LoadingDialog;

/**
 * @ClassName: SignInDetailActivity
 * @Description: 社区服务、教育学习详细类，支持各种签到、拍照、录音及上传功能
 * @Author: John zhuqiangping@gmail.com
 * @Date: 2014年11月12日
 * 
 */
public class SignInDetailActivity extends Activity implements OnClickListener,
		OnStateChangedListener, StopRecordCallback {
	private static final String TAG = "SignInDetailActivity";
	static final String STATE_FILE_NAME = "soundrecorder.state";
	static final String RECORDER_STATE_KEY = "recorder_state";
	static final String SAMPLE_INTERRUPTED_KEY = "sample_interrupted";
	static final String MAX_FILE_SIZE_KEY = "max_file_size";

	private static final boolean DEBUG = false;

	private static final int MSG_LOAD_DATA = 1; // 初始化后加载数据
	private static final int MSG_UPDATE_UI = 2; // 刷新界面UI

	private static final long MAX_RECORD_TIME = 24 * 60 * 60L;
	private static final long ANIMATION_DURATION = 200L;

	public static final int RESULT_OK = 1001;
	public static final int SPONSOR_CHOOSE_PHOTO_REQUEST = 1002;
	public static final int SIGNIN_CHOOSE_PHOTO_REQUEST = 1003;

	private static final long FINGER_AGAIN_TIME = 1500L;

	private AppContext mAppContext;
	private KJDB mKjdb;

	private SponsorInfo mSponsorInfo; // 当前社区服务或者教育学习

	private Button mBackBtn; // 标题栏中back按钮
	private TextView mTitleView; // 标题栏中标题名

	private TextView mSoundRecordName;
	private TextView mSignInDetailTime;
	private TextView mSignInDetailAddress;
	private TextView mSignInDetailContent;
	private View mBaseDetail;
	private View mOthersDetail;
	private View mContentDetail;
	private View mControlDetail;
	private ExpandListView mListView;
	private TextView mSigninNote;

	private Button mBeginSignIn; // 开始签到
	private Button mCallSignIn; // 点名签到
	private Button mEndSignIn; // 结束签到
	private Button mCheckRecord; // 查看签到记录
	private Button mSoundRecord; // 录音
	private Button mTakePicture; // 拍照
	private Button mUploadRecord; // 上传记录
	private GridView mGridPictures; // 照片集合图
	private String mFlag; // 签到类型 0开始签到，1点名签到，2结束签到
	private String mRegisterType = "1"; // 0-集中教育 1-集中劳动 2-个别教育 3-个别劳动
	private SignInRecordAdapter mAdapter;

	private List<SignInRecordBean> mRecordList;
	private PictureGridAdapter mPictureGridAdapter;
//	private ProgressDialog mUploadDialog; // 上传记录对话框
	private int mUploadIndex = 0; // 上传序列
	private boolean mAnimationRunning = false; // 动画运行中
	private boolean mExpandShow = false; // 展开签到详细界面
	private float mOffsetY = 0; // Y轴动画偏移量

	private int mChooseImageCount = 3;
	private int mTakePictureItem = -1;

	private List<String> mCacheCheckImages = new ArrayList<String>();

	int mAudioSourceType = MediaRecorder.AudioSource.MIC;
	String mRequestedType = DataConfig.AUDIO_AMR;

	private AudioManager mAudioManager;
	private String mLastFileName;

	private boolean mStartNewInstance = false;
	private boolean mNeedLoadData = true;
	private SoundRecorder mRecorder;
	long mMaxFileSize = -1; // can be specified in the intent
	private RemainingTimeCalculator mRemainingTimeCalculator;
	private String mErrorUiMessage = null;
	private boolean mSampleInterrupted = false;

	private SoundRecorderService mService = null;
	private MatchFingerprintSyncLogic mLogic;
	private int mSponsorType = 0;// 签到方式 0指纹，1，平台录入，2打卡
	private LoadingDialog mProgressDialog;

	private ServiceConnection mServiceConnection = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			Log.i(TAG, "<onServiceConnected> Service connected");
			mService = ((SoundRecorderBinder) service).getService();
			mRecorder = mService.getRecorder();
			mRecorder.setOnStateChangedListener(SignInDetailActivity.this);
			mRemainingTimeCalculator = mService.getRemainingTimeCalculator();
			updateUi();
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			Log.i(TAG, "<onServiceDisconnected> Service dis connected");
			mService = null;
		}
	};

	private String mTimerFormat;
	private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MSG_LOAD_DATA:
				if (mSponsorInfo != null) {
					// 从数据库中加载录音信息，仅支持集中劳动和集中教育
					StringBuilder where = new StringBuilder();
					where.append("sponsorType = '");
					where.append(mRegisterType);
					where.append("' and sponsorId = '");
					where.append(mSponsorInfo.getSponsorId());
					where.append("'and fileType = 2");
					List<ImageOrAudioBean> list = new ArrayList<ImageOrAudioBean>();
					try {
						list = mKjdb.findAllByWhere(
								ImageOrAudioBean.class, where.toString());
					} catch (Exception e) {
					}
					if (list != null && !list.isEmpty()) {
						// 默认情况下只有一条数据，故使用第一条数据
						mLastFileName = list.get(0).getFileName();
						mSoundRecordName.setText(mLastFileName);
						mSoundRecord.setEnabled(false);
					}
					// 从数据库中加载图片资源
					mPictureGridAdapter.clear(); // 清空数组
					StringBuilder where2 = new StringBuilder();
					where2.append("sponsorType = '");
					where2.append(mRegisterType);
					where2.append("' and sponsorId = '");
					where2.append(mSponsorInfo.getSponsorId());
					where2.append("'and fileType = 1");
					List<ImageOrAudioBean> list2 = new ArrayList<ImageOrAudioBean>();
					try {
						list2 = mKjdb.findAllByWhere(
								ImageOrAudioBean.class, where2.toString());
					} catch (Exception e) {
						// TODO: handle exception
					}
					if (list2 != null && !list2.isEmpty()) {
						for (ImageOrAudioBean bean : list2) {
							mPictureGridAdapter.addBitmap(bean.getFilePath());
						}
					}
				}
				
				// 从数据库中加载签到信息
				StringBuilder where = new StringBuilder();
				where.append("type = '");
				where.append(mRegisterType);
				where.append("' and state = 1");
				if (mSponsorInfo != null) {
					where.append(" and sponsorId = '");
					where.append(mSponsorInfo.getSponsorId());
					where.append("'");
				}
				try {
					mRecordList = mKjdb.findAllByWhere(SignInRecordBean.class,
							where.toString());
					Collections.sort(mRecordList, mRecordComparator);
				} catch (Exception e) {
				}
				mAdapter.setSignInRecordList(mRecordList);
				mAdapter.notifyDataSetChanged();
				break;
			}
		}

	};

	final Comparator mRecordComparator = new Comparator<SignInRecordBean>() {

		@Override
		public int compare(SignInRecordBean arg0, SignInRecordBean arg1) {
			Date date0 = DataUtils.convertStrToDate(arg0.getTime(),
					DateFormat.DATE_YMD_HMS);
			Date date1 = DataUtils.convertStrToDate(arg1.getTime(),
					DateFormat.DATE_YMD_HMS);
			if (date0.before(date1)) {
				return 1;
			}
			return -1;
		}

	};

	Runnable mUpdateTimer = new Runnable() {
		public void run() {
			updateTimerView();
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mStartNewInstance = false;
		mNeedLoadData = true;
		if (savedInstanceState != null) {
			Bundle recorderState = savedInstanceState
					.getBundle(RECORDER_STATE_KEY);
			if (mRecorder != null && recorderState != null) {
				mRecorder.saveState(recorderState);
			}
		}
		mAppContext = (AppContext) getApplication();
		mKjdb = mAppContext.getKjdb();
		mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
		mProgressDialog = new LoadingDialog(this);
		setContentView(R.layout.activity_singindetail);
		initView();
		initFinger();
	}
	
	// 初始化指纹信息
	private void initFinger() {
		MtRfid.getInstance().RfidInit();
		MtRfid.getInstance().SetContext(this);
		mLogic = MatchFingerprintSyncLogic.getInstance();
		mLogic.setFingerPrintReader(FingerprintManager.getInstance()
				.getNewAsyncFingerprint());
		mLogic.setHandle(mFingerpringHandler);
		mLogic.isManager(false);
	}

	@Override
	protected void onNewIntent(Intent intent) {
		mStartNewInstance = true;
		mNeedLoadData = true;
		super.onNewIntent(intent);
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (mStartNewInstance) {
			updateServiceStatus();
		}
		if (mNeedLoadData) {
			mNeedLoadData = false;
			mHandler.sendEmptyMessage(MSG_LOAD_DATA);
		}
		Log.i(TAG, "<onResume> start service");
		if (startService(new Intent(this, SoundRecorderService.class)) == null) {
			Log.e(TAG, "<onResume> fail to start service");
			finish();
			return;
		}
		bindService(new Intent(this, SoundRecorderService.class),
				this.mServiceConnection, BIND_AUTO_CREATE);
	}

	// 初始化数据
	private void initView() {
		mTimerFormat = getResources().getString(R.string.timer_format);

		mBackBtn = (Button) this.findViewById(R.id.header_back);
		mBackBtn.setOnClickListener(this);

		mTitleView = (TextView) this.findViewById(R.id.header_title);
		mTitleView.setText(R.string.centralized_labor);

		Bundle extras = getIntent().getExtras();
		if (extras != null) {
			if (extras.containsKey("SponsorInfo")) {
				mSponsorInfo = (SponsorInfo) extras.get("SponsorInfo");
			}
			if (extras.containsKey("title")) {
				mTitleView.setText(extras.getString("title"));
			}

			mRegisterType = extras.getString("registerType",
					DataConfig.REGISTER_TYPE_1);
		}

		mBaseDetail = this.findViewById(R.id.singindetail_base);
		mSignInDetailTime = (TextView) mBaseDetail
				.findViewById(R.id.signin_detail_date);
		mSignInDetailAddress = (TextView) mBaseDetail
				.findViewById(R.id.signin_detail_address);
		mSignInDetailContent = (TextView) mBaseDetail
				.findViewById(R.id.signin_detail_content);

		mOthersDetail = this.findViewById(R.id.singindetail_others);
		mSoundRecordName = (TextView) mOthersDetail
				.findViewById(R.id.record_name);

		mContentDetail = this.findViewById(R.id.singindetail_content);
		mListView = (ExpandListView) this.findViewById(R.id.singindetail_list);
		mControlDetail = this.findViewById(R.id.singindetail_control);
		mSigninNote = (TextView) this.findViewById(R.id.signin_note);

		TextView emptyView = (TextView) this
				.findViewById(R.id.signin_detail_empty_pictures);
		mGridPictures = (GridView) this
				.findViewById(R.id.signin_detail_grid_pictures);
		mGridPictures.setEmptyView(emptyView);
		mPictureGridAdapter = new PictureGridAdapter(this);
		mGridPictures.setAdapter(mPictureGridAdapter);

		mBeginSignIn = (Button) this.findViewById(R.id.bengin_signin);
		mBeginSignIn.setOnClickListener(this);
		mCallSignIn = (Button) this.findViewById(R.id.call_signin);
		mCallSignIn.setOnClickListener(this);
		mEndSignIn = (Button) this.findViewById(R.id.end_signin);
		mEndSignIn.setOnClickListener(this);
		mCheckRecord = (Button) this.findViewById(R.id.check_record);
		mCheckRecord.setOnClickListener(this);
		mSoundRecord = (Button) this.findViewById(R.id.sound_record);
		mSoundRecord.setOnClickListener(this);
		mTakePicture = (Button) this.findViewById(R.id.take_picture);
		mTakePicture.setOnClickListener(this);
		mUploadRecord = (Button) this.findViewById(R.id.upload_record);
		mUploadRecord.setOnClickListener(this);

		mAdapter = new SignInRecordAdapter(this);
		mListView.setAdapter(mAdapter);

		if (mSponsorInfo != null) {
			mSignInDetailTime.setText(mSponsorInfo.getTime());
			mSignInDetailAddress.setText(mSponsorInfo.getAddress());
			mSignInDetailContent.setText(mSponsorInfo.getContent());
		} else {
			mAdapter.setTakePictureListener(this);
			mSignInDetailTime.setText("--");
			mSignInDetailAddress.setText("--");
			mSignInDetailContent.setText("--");
			mOthersDetail.setVisibility(View.GONE);
			mSigninNote.setVisibility(View.VISIBLE);
			mSoundRecord.setVisibility(View.GONE);
			mTakePicture.setVisibility(View.GONE);
		}

//		mUploadDialog = new ProgressDialog(this);
//		mUploadDialog.setCancelable(false);
//		mUploadDialog.setTitle(R.string.upload_record);
	}

	/**
	 * To get service status when the service of sound recording is going
	 */
	private void updateServiceStatus() {
		if (mService == null) {
			return;
		}
		SponsorInfo sb = mService.getSponsorInfo();
		if (mSponsorInfo != null
				&& mSponsorInfo.getSponsorId().equals(sb.getSponsorId())) {
			// 当前界面的活动与正在录音的活动为同一个时，不需要更新数据
			Log.i(TAG,
					"<updateServiceStatus> at the same SponsorInfo activity!");
			return;
		} else {
			mSponsorInfo = sb;

		}
		mTitleView.setText(mService.getTitleName());
		mRegisterType = mService.getRegisterType();

		// 重置基本信息
		mSignInDetailTime.setText(mSponsorInfo.getTime());
		mSignInDetailAddress.setText(mSponsorInfo.getAddress());
		mSignInDetailContent.setText(mSponsorInfo.getContent());
		mOthersDetail.setVisibility(View.VISIBLE);
		mSigninNote.setVisibility(View.GONE);
		mSoundRecord.setVisibility(View.VISIBLE);
		mTakePicture.setVisibility(View.VISIBLE);
		mSoundRecord.setEnabled(true);
		updateUi();
	}

	/**
	 * Shows/hides the appropriate child views for the new state.
	 */
	private void updateUi() {
		Log.i(TAG, "updateUi state : " + mService.getRecordState());
		switch (mService.getRecordState()) {
		case SoundRecorder.STATE_IDLE:
			if (mLastFileName == null) {
				mSoundRecordName.setText("无");
			} else {
				mSoundRecordName.setText(mLastFileName);
			}
			mSoundRecord.setText(R.string.sound_record);
			break;
		case SoundRecorder.STATE_RECORDING:
			SponsorInfo sb = mService.getSponsorInfo();
			if (mSponsorInfo != null
					&& mSponsorInfo.getSponsorId().equals(sb.getSponsorId())) {
				mSoundRecord.setText(R.string.stop_record);
				createFileName();
			} else {
				mSoundRecord.setEnabled(false);
				return;
			}

			break;
		case SoundRecorder.STATE_STOP_RECORDING:
			mSoundRecord.setText(R.string.sound_record);
			break;
		}
		updateTimerView();
	}

	private void createFileName() {
		String fileName = mRecorder.sampleFile().getName();
		mLastFileName = fileName.substring(0, fileName.lastIndexOf(".tmp"));
	}

	/**
	 * Update the big MM:SS timer. If we are in playback, also update the
	 * progress bar.
	 */
	private void updateTimerView() {
		int state = mService.getRecordState();

		boolean ongoing = state == SoundRecorder.STATE_RECORDING
				|| state == SoundRecorder.STATE_PLAYING;

		long time = ongoing ? mService.getCurrentRecordProgress() : mService
				.getRecordSampleLength();

		if (ongoing && time < MAX_RECORD_TIME) {
			String timeStr = String.format(mTimerFormat, time / 60 / 60,
					time / 60, time % 60);
			mSoundRecordName.setText(timeStr);
		}

		if (state == SoundRecorder.STATE_PLAYING) {
			// mStateProgressBar.setProgress((int)(100*time/mRecorder.sampleLength()));
		} else if (state == SoundRecorder.STATE_RECORDING) {
			updateTimeRemaining();
		}

		if (ongoing)
			mHandler.postDelayed(mUpdateTimer, 1000);
	}

	/*
	 * Called when we're in recording state. Find out how much longer we can go
	 * on recording. If it's under 5 minutes, we display a count-down in the UI.
	 * If we've run out of time, stop the recording.
	 */
	private void updateTimeRemaining() {
		long t = mRemainingTimeCalculator.timeRemaining();

		if (t <= 0) {
			mSampleInterrupted = true;

			int limit = mRemainingTimeCalculator.currentLowerLimit();
			switch (limit) {
			case RemainingTimeCalculator.DISK_SPACE_LIMIT:
				mErrorUiMessage = getResources().getString(
						R.string.storage_is_full);
				break;
			case RemainingTimeCalculator.FILE_SIZE_LIMIT:
				mErrorUiMessage = getResources().getString(
						R.string.max_length_reached);
				Toast.makeText(SignInDetailActivity.this, mErrorUiMessage,
						Toast.LENGTH_SHORT).show();
				break;
			default:
				mErrorUiMessage = null;
				break;
			}
			mService.stopRecording();
			return;
		}

	}

	private void setAllButtonEnabled(boolean enable) {
		mBeginSignIn.setEnabled(enable);
		mCallSignIn.setEnabled(enable);
		mEndSignIn.setEnabled(enable);
		mCheckRecord.setEnabled(enable);
		mTakePicture.setEnabled(enable);
		mUploadRecord.setEnabled(enable);
	}

	/**
	 * 上传录音和照片
	 */
	private void uploadImageOrAudio() {
//		mUploadDialog.setMessage("请稍等，资源正在上传中...");
//		mUploadDialog.show();
		UploadToTempSyncLogic logic = new UploadToTempSyncLogic(
				mAppContext, mUploadHandler, true, mRegisterType);
		logic.execute();
	}

	/**
	 * 上传签到记录和各种资源
	 */
	private void upload(int index) {
		// 上传签到记录
		SignInUploadLogic logic = new SignInUploadLogic(mAppContext,
				mUploadHandler, mRegisterType);
		logic.execute();
		
		/*
		if (mRecordList != null && !mRecordList.isEmpty()) {
			if (index < mRecordList.size()) {
				mUploadIndex++;

				SignInRecordBean bean = mRecordList.get(index);
				if (bean.getState() == 1) {
					SignInUploadLogic uploadLogic = new SignInUploadLogic(
							mAppContext, mUploadHandler, bean);
					uploadLogic.execute();

					mUploadDialog.setMessage(bean.getName());
					mUploadDialog.show();
				} else {
					upload(mUploadIndex);
				}
				return;
			} else {
				// reset mUploadIndex
				mUploadIndex = 0;
				// 上传操作后刷新界面
				System.out.println("上传成功  => 刷新界面！！");
				mHandler.sendEmptyMessage(MSG_LOAD_DATA);
			}
		}
		// 上传录音、照片等资源
		if (mSponsorInfo != null) {
		    uploadImageOrAudio();
		} else {
			mUploadDialog.cancel();
		}
		*/
	}

	private Handler mUploadHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			//TODO 更新视图
			mHandler.sendEmptyMessage(MSG_LOAD_DATA);
			
			switch (msg.what) {
			case UIHelper.SIGNIN_UPLOAD_SUCCESS:
				// 上传成功
//				List<String> values = (List<String>) msg.obj;
//				SignInRecordBean bean = mRecordList.get(mUploadIndex - 1);
//				bean.setState(2); // 已上传
//				bean.setEduComld(values.get(0));
//				// 更新签到状态
//				mKjdb.update(bean);
				//TODO 上传资源
				uploadImageOrAudio();
				break;
			case UIHelper.SIGNIN_UPLOAD_ERROR:
			case UIHelper.SIGNIN_UPLOAD_FAIL:
				// 上传签到失败 --不区别失败的种类
				// upload(mUploadIndex);
				uploadImageOrAudio();
				break;
			case UIHelper.FILE_UPLOAD_SUCCESS:
//				mUploadDialog.cancel();
				if (mProgressDialog != null) {
					mProgressDialog.dismiss();
				}
				Toast.makeText(mAppContext, "记录上传成功！", Toast.LENGTH_SHORT)
						.show();
				break;
			case UIHelper.FILE_UPLOAD_FAIL:
//				mUploadDialog.cancel();
				if (mProgressDialog != null) {
					mProgressDialog.dismiss();
				}
				Toast.makeText(mAppContext, "记录上传失败！", Toast.LENGTH_SHORT)
						.show();
				break;
			default:
				break;
			}
		}

	};

	/**
	 * 执行指纹验证
	 */
	private void validateFingerPrint() {
		if (DEBUG) {
			// 调试--模拟指纹签到
			List<FingerPrintBean> list = mKjdb.findAllByWhere(
					FingerPrintBean.class, "type=1");
			if (list == null || list.isEmpty()) {
				FingerPrintBean bean = new FingerPrintBean();
				bean.setUserName("李峰");
				bean.setUserId("2000001480");
				bean.setType(1);
				addSignInRecord(bean);
			} else {
				Random radom = new Random();
				int i = radom.nextInt(list.size());
				FingerPrintBean bean = list.get(i);
				addSignInRecord(bean);
			}
		} else {
			mProgressDialog.setMessage("请按指纹...");
			mProgressDialog.show();
			mLogic.execute();
			mProgressDialog.setMatchLogic(mLogic);
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.bengin_signin:
			// 开始签到
			mFlag = DataConfig.SIGN_FLAG_BEGIN;
			validateFingerPrint();
			break;
		case R.id.call_signin:
			// 点名签到
			mFlag = DataConfig.SIGN_FLAG_CALL;
			validateFingerPrint();
			break;
		case R.id.end_signin:
			// 结束签到
			mFlag = DataConfig.SIGN_FLAG_END;
			validateFingerPrint();
			break;
		case R.id.check_record:
			// 查看记录
			expandRecordList();
			break;
		case R.id.sound_record:
			// 录音
			onClickRecordButton();
			break;
		case R.id.take_picture:
			// 拍照
			Intent takePicture = new Intent(this, ChoosePhotoActivity.class);
			takePicture.putExtra(ChoosePhotoActivity.CHOOSE_PHOTO_COUNT,
					mChooseImageCount);
			startActivityForResult(takePicture, SPONSOR_CHOOSE_PHOTO_REQUEST);
			break;
		case R.id.upload_record:
			// 记录上传
			mProgressDialog.setMessage("请稍等,记录正在上传中...");
			mProgressDialog.show();
			upload(0);
			break;
		case R.id.header_back:
			if (mExpandShow) {
				shrinkRecordList();
			} else {
				finish();
			}
			break;
		case R.id.sign_note:
			try {
				mTakePictureItem = Integer.parseInt(v.getTag().toString());
				// 拍照（个别劳动/个别教育-开始签到）
				Intent takePicture2 = new Intent(this,
						ChoosePhotoActivity.class);
				takePicture2
						.putExtra(ChoosePhotoActivity.CHOOSE_PHOTO_COUNT, 1);
				startActivityForResult(takePicture2,
						SIGNIN_CHOOSE_PHOTO_REQUEST);
			} catch (NumberFormatException e) {
				Log.e(TAG, "Parse " + v.getTag() + " to integer ERROR!");
			}
			break;
		}

	}

	/**
	 * 展开签到记录布局
	 */
	private void expandRecordList() {
		if (mExpandShow || mAnimationRunning)
			return;

		if (mOffsetY == 0) {
			mOffsetY = mContentDetail.getY() - mBaseDetail.getY();
		}

		float y = mBaseDetail.getY();
		ObjectAnimator baseAnimator = ObjectAnimator.ofFloat(mBaseDetail, "y",
				y - mOffsetY);
		baseAnimator.setDuration(ANIMATION_DURATION);

		y = mOthersDetail.getY();
		ObjectAnimator detailAnimator = ObjectAnimator.ofFloat(mOthersDetail,
				"y", y - mOffsetY);
		detailAnimator.setDuration(ANIMATION_DURATION);

		y = mContentDetail.getY();
		ObjectAnimator contentAnimator = ObjectAnimator.ofFloat(mContentDetail,
				"y", y - mOffsetY);
		contentAnimator.setDuration(ANIMATION_DURATION);

		y = mListView.getY();
		ObjectAnimator listAnimator = ObjectAnimator.ofFloat(mListView, "y", y
				- mOffsetY);
		listAnimator.setDuration(ANIMATION_DURATION);

		y = mControlDetail.getY();
		ObjectAnimator controlerAnimator = ObjectAnimator.ofFloat(
				mControlDetail, "y", y + mControlDetail.getMeasuredHeight());
		controlerAnimator.setDuration(ANIMATION_DURATION);

		AnimatorSet set = new AnimatorSet();
		set.playTogether(baseAnimator, detailAnimator, contentAnimator,
				listAnimator, controlerAnimator);
		set.addListener(new AnimatorListener() {

			@Override
			public void onAnimationCancel(Animator arg0) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onAnimationEnd(Animator arg0) {
				mExpandShow = true;
				mAnimationRunning = false;
				mTitleView.setText(R.string.check_record);
			}

			@Override
			public void onAnimationRepeat(Animator arg0) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onAnimationStart(Animator arg0) {
				mAnimationRunning = true;
				Log.i(TAG, "start to enpand RecordList!");
			}

		});
		set.start();
	}

	/**
	 * 收起签到详情状态
	 */
	private void shrinkRecordList() {
		if (!mExpandShow || mAnimationRunning)
			return;

		float y = mBaseDetail.getY();
		ObjectAnimator baseAnimator = ObjectAnimator.ofFloat(mBaseDetail, "y",
				y + mOffsetY);
		baseAnimator.setDuration(ANIMATION_DURATION);

		y = mOthersDetail.getY();
		ObjectAnimator detailAnimator = ObjectAnimator.ofFloat(mOthersDetail,
				"y", y + mOffsetY);
		detailAnimator.setDuration(ANIMATION_DURATION);

		y = mContentDetail.getY();
		ObjectAnimator contentAnimator = ObjectAnimator.ofFloat(mContentDetail,
				"y", y + mOffsetY);
		contentAnimator.setDuration(ANIMATION_DURATION);

		y = mListView.getY();
		ObjectAnimator listAnimator = ObjectAnimator.ofFloat(mListView, "y", y
				+ mOffsetY);
		listAnimator.setDuration(ANIMATION_DURATION);

		y = mControlDetail.getY();
		ObjectAnimator controlerAnimator = ObjectAnimator.ofFloat(
				mControlDetail, "y", y - mControlDetail.getMeasuredHeight());
		controlerAnimator.setDuration(ANIMATION_DURATION);

		AnimatorSet set = new AnimatorSet();
		set.playTogether(baseAnimator, detailAnimator, contentAnimator,
				listAnimator, controlerAnimator);
		set.addListener(new AnimatorListener() {

			@Override
			public void onAnimationCancel(Animator arg0) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onAnimationEnd(Animator arg0) {
				mExpandShow = false;
				mAnimationRunning = false;
				mTitleView.setText(R.string.centralized_labor);
			}

			@Override
			public void onAnimationRepeat(Animator arg0) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onAnimationStart(Animator arg0) {
				mAnimationRunning = true;
				Log.i(TAG, "start to shrink RecordList!");
			}

		});
		set.start();
	}

	void onClickRecordButton() {
		final int state = mService.getRecordState();
		switch (state) {
		case SoundRecorder.STATE_PAUSE_RECORDING:
			mService.resumeRecording();
			updateUi();
			return;
		case SoundRecorder.STATE_RECORDING:
			mService.stopRecording();
//			updateUi();
//			showSaveRecordDialog();
			return;
		case SoundRecorder.STATE_IDLE:
			mRemainingTimeCalculator.reset();
			mService.stopAudioPlayback();
			mService.setTitleName(mTitleView.getText().toString());
			mService.setSponsorInfo(mSponsorInfo);
			mService.setRegisterType(mRegisterType);
			mService.setNotificationClass(this.getClass());
//			mService.setStopRecordCallback(this);

			if ((mAudioManager.getMode() == AudioManager.MODE_IN_CALL)
					&& (mAudioSourceType == MediaRecorder.AudioSource.MIC)) {
				mAudioSourceType = MediaRecorder.AudioSource.VOICE_UPLINK;
				mService.setAudioSourceType(mAudioSourceType);
				Log.e(TAG, "Selected Voice Tx only Source: sourcetype"
						+ mAudioSourceType);
			}

			if (mMaxFileSize != -1 && mMaxFileSize < 1024 * 5) {
				Toast.makeText(this, R.string.max_length_reached,
						Toast.LENGTH_SHORT).show();
				return;
			}

			mService.record(mRequestedType);

			if (mMaxFileSize != -1) {
				mRemainingTimeCalculator.setFileSizeLimit(
						mService.getRecordSampleFile(), mMaxFileSize);
			}

			updateUi();
			return;
		}
	}

	private void showSaveRecordDialog() {
		LayoutInflater inflater = LayoutInflater.from(this);
		View contentView = inflater.inflate(R.layout.recordsave_dialog, null);
		AlertDialog.Builder build = new AlertDialog.Builder(this);
		final EditText renameView = (EditText) contentView
				.findViewById(R.id.record_renme_et);
		if (mLastFileName == null) {
			String path = mService.getRecordSampleFile().getName();
			String fileName = path.substring(
					1 + path.lastIndexOf(File.separator), path.length());
			if (fileName.endsWith(".tmp"))
				fileName = fileName.substring(0, fileName.lastIndexOf(".tmp"));
			mLastFileName = fileName;
		}
		renameView.setText(mLastFileName);
		renameView.setSelection(mLastFileName.length());
		build.setView(contentView);
		build.setTitle(R.string.record_rename);
		build.setCancelable(false);
		build.setPositiveButton(R.string.save_record,
				new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						try {
							Field f = dialog.getClass().getSuperclass()
									.getDeclaredField("mShowing");
							f.setAccessible(true);
							f.set(dialog, false);
						} catch (Exception e) {
							e.printStackTrace();
						}

						String newName = renameView.getText().toString();
						if (newName != null && !newName.equals(mLastFileName)) {
							mLastFileName = newName;
						}

						if (saveSample()) {
							try {
								Field f = dialog.getClass().getSuperclass()
										.getDeclaredField("mShowing");
								f.setAccessible(true);
								f.set(dialog, true);
							} catch (Exception e) {
								e.printStackTrace();
							}
							mSoundRecord.setEnabled(false);
							updateUi();
						}
					}
				});
		build.setNegativeButton(android.R.string.cancel,
				new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						try {
							Field f = dialog.getClass().getSuperclass()
									.getDeclaredField("mShowing");
							f.setAccessible(true);
							f.set(dialog, true);
						} catch (Exception e) {
							e.printStackTrace();
						}
						mService.deleteRecord();
						mSoundRecord.setEnabled(true);
						mLastFileName = null;
						updateUi();
					}
				});

		AlertDialog renameDialog = build.create();
		renameDialog.show();
		final Button positiveButton = renameDialog
				.getButton(AlertDialog.BUTTON_POSITIVE);
		renameView.addTextChangedListener(new TextWatcher() {
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				if (s.toString().length() <= 0
						|| s.toString().matches(".*[/\\\\:*?\"<>|].*")
						|| !s.toString().matches(
								"[a-zA-Z0-9_.\\-\\s\u4e00-\u9fa5]+")) {
					String inputText = "";
					try {
						inputText = s.subSequence(start, start + count)
								.toString();
					} catch (IndexOutOfBoundsException ex) {
					}
					if (inputText.length() > 0
							&& ((inputText.matches(".*[/\\\\:*?\"<>|].*")) || !s
									.toString()
									.matches(
											"[a-zA-Z0-9_.\\-\\s\u4e00-\u9fa5]+"))) {
						Toast.makeText(SignInDetailActivity.this,
								R.string.invalid_char_prompt,
								Toast.LENGTH_SHORT).show();
					}
					if (positiveButton != null) {
						positiveButton.setEnabled(false);
					}
				} else {
					if (positiveButton != null) {
						positiveButton.setEnabled(true);
					}
				}
			}

			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
			}
		});
	}

	private boolean saveSample() {
		if (mService.saveRecord(mLastFileName, mRequestedType)) {
			// 保存音频资源到数据库
			ImageOrAudioBean bean = new ImageOrAudioBean();
			bean.setSponsorType(mRegisterType);
			if (mSponsorInfo != null) {
				bean.setSponsorId(mSponsorInfo.getSponsorId());
			}
			bean.setFileName(mLastFileName);
			bean.setFileType(2);
			bean.setServiceId(3);
			String path = mRecorder.getSampleDir().getAbsolutePath() + "/"
					+ mLastFileName + mRecorder.getType();
			bean.setFilePath(path);
			bean.setState(1);
			bean.setImie(mAppContext.getImei());
			mKjdb.save(bean);

			updateUi();
			return true;
		} else {
			mLastFileName = null;
			return false;
		}
	}

	private Runnable mFingerAgainRunnable = new Runnable() {

		@Override
		public void run() {
			validateFingerPrint();
		}

	};

	private Handler mFingerpringHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			mSponsorType = 0;
			switch (msg.what) {
			case UIHelper.FINGERPRINT_UPCHAR_SUCCESS:
				break;
			case UIHelper.FINGERPRINT_UPCHAR_FAIL:// char--返回失败
			case UIHelper.FINGERPRINT_REGMODE_FAIL:// char--模板合成失败
			case UIHelper.FINGERPRINT_GENCHAR_FAIL:// char--生成特征值失败
			case UIHelper.FINGERPRINT_DELETECHAR_FAIL:// char--模板下载失败
			case UIHelper.FINGERPRINT_UPIMAGE_FAIL:// image--生成失败
			case UIHelper.FINGERPRINT_SEARCH_FAIL:
				if (mProgressDialog != null) {
					mProgressDialog.dismiss();
				}
				// 匹配失败
				Toast.makeText(SignInDetailActivity.this, "没有找到匹配的指纹",
						Toast.LENGTH_SHORT).show();
				// 重试
//				if (mLogic != null) {
//					mLogic.destory();
//				}
				new Handler().postDelayed(mFingerAgainRunnable,
						FINGER_AGAIN_TIME);
				break;
			case UIHelper.FINGERPRINT_SEARCH_SUCCESS:
				// 匹配成功
				if (mProgressDialog != null) {
					mProgressDialog.dismiss();
				}
				int pageId = msg.arg1;
				mSponsorType = msg.arg2;
				try {
					FingerPrintBean fingerPrintBean = mKjdb.findById(pageId,
							FingerPrintBean.class);
					addSignInRecord(fingerPrintBean);
					
				} catch (Exception e) {
				}
				// 重试
//				if (mLogic != null) {
//					mLogic.destory();
//				}
				new Handler().postDelayed(mFingerAgainRunnable,
						FINGER_AGAIN_TIME);
				break;
			case UIHelper.FINGERPRINT_AGAIN:// 再次按手指
				mProgressDialog.setMessage("请再次按指纹...");
				mProgressDialog.show();
			case UIHelper.FINGERPRINT_ONMATCH_SUCCESS:// image--图片合成成功

				break;

			default:
				break;
			}
		};

	};

	/**
	 * 添加签到信息
	 * 
	 * @param fingerPrintBean
	 *            FingerPrintBean
	 */
	private void addSignInRecord(FingerPrintBean fingerPrintBean) {
		if (fingerPrintBean != null && fingerPrintBean.getType() == 1) {
			Toast.makeText(SignInDetailActivity.this, "匹配成功",
					Toast.LENGTH_SHORT).show();
			SignInRecordBean bean = new SignInRecordBean();
			bean.setName(fingerPrintBean.getUserName());
			String time = DataUtils.converDatLongToString(
					System.currentTimeMillis(), DateFormat.DATE_YMD_HMS);
			bean.setTime(time);
			bean.setFlag(mFlag);
			bean.setState(1);
			bean.setType(mRegisterType);
			bean.setSponsorType(String.valueOf(mSponsorType));
			if (mSponsorInfo != null) {
				bean.setSponsorId(mSponsorInfo.getSponsorId());
			} else {
				bean.setSponsorId("");
			}
			//bean.setSponsorType(DataConfig.SIGN_TYPE_FINGERPRINT);
			bean.setElectronicsId(fingerPrintBean.getUserId());
			bean.setImie(mAppContext.getImei());
			// 保存bean到数据库
			mKjdb.save(bean);
			DbModel dbModel = mKjdb
					.findDbModelBySQL("select max(id) as id from table_signInRecord order by id desc");
			int mMaxId = dbModel.getInt("id");
			Log.i(TAG, "-----》 id：" + mMaxId);
			bean.setId(mMaxId);
			mRecordList.add(bean);
			Collections.sort(mRecordList, mRecordComparator);
			mAdapter.setSignInRecordList(mRecordList);
			mAdapter.notifyDataSetChanged();
			mListView.setSelection(0);
		} else {
			Toast.makeText(SignInDetailActivity.this, "匹配失败",
					Toast.LENGTH_SHORT).show();
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode,
			final Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		Log.i(TAG, "----onActivityResult--->requestCode:" + requestCode + ",resultCode:" + resultCode);
		if (requestCode == SPONSOR_CHOOSE_PHOTO_REQUEST
				&& resultCode == RESULT_OK) {
			//集中签到选取图片
			new Thread(new Runnable() {

				@Override
				public void run() {
					//TODO 待优化，此处还需要可以删除，修改图片
					mCacheCheckImages = data
							.getStringArrayListExtra("mCacheCheckImages");
					if (mCacheCheckImages != null
							&& !mCacheCheckImages.isEmpty()
							&& mCacheCheckImages.size() > 0) {
						mPictureGridAdapter.clear();
						// 清除数据库中该活动的所有图片记录，否则记录将重复或超过上限
						StringBuilder where = new StringBuilder();
						where.append("sponsorType = '");
						where.append(mRegisterType);
						where.append("'");
						if (mSponsorInfo != null) {
							where.append(" and sponsorId = '");
							where.append(mSponsorInfo.getSponsorId());
							where.append("'");
						}
						where.append(" and fileType = 1");
						mKjdb.deleteByWhere(ImageOrAudioBean.class,
								where.toString());
						for (int i = 0; i < mCacheCheckImages.size(); i++) {
							String path = mCacheCheckImages.get(i);
							Log.i(TAG, "select picture path:" + path);
							boolean success = mPictureGridAdapter
									.addBitmap(path);
							if (success) {
								// 保存当前活动中（集中劳动或集中教育）该图片记录
								ImageOrAudioBean bean = DataHelper
										.getImageOrAudioBeanInfoByPath(
												mAppContext, path, 1);
								bean.setSponsorType(mRegisterType);
								if (mSponsorInfo != null) {
									bean.setSponsorId(mSponsorInfo
											.getSponsorId());
									bean.setServiceId(3);
								}else {
									bean.setServiceId(2);
								}
								bean.setImie(mAppContext.getImei());
								mKjdb.save(bean);
							}
						}
					}
				}
			}).run();
		}
		if (requestCode == SIGNIN_CHOOSE_PHOTO_REQUEST
				&& resultCode == RESULT_OK) {
			//个别签到，选取图片
			new Thread(new Runnable() {

				@Override
				public void run() {
					mCacheCheckImages = data
							.getStringArrayListExtra("mCacheCheckImages");
					if (mCacheCheckImages != null
							&& !mCacheCheckImages.isEmpty()
							&& mCacheCheckImages.size() > 0) {
						String filePath = mCacheCheckImages.get(0);
						Log.i(TAG, "----onActivityResult--->filePath:"
								+ filePath + ",mTakePictureItem："
								+ mTakePictureItem);
						if (mTakePictureItem >= 0 && mRecordList != null && !StringUtils.isEmpty(filePath)) {
							SignInRecordBean bean = mRecordList
									.get(mTakePictureItem);
							if (bean != null) {
								bean.setFilePath(filePath);
								mKjdb.update(bean);
								mAdapter.notifyDataSetChanged();
								//TODO 添加到资源数据库中
								ImageOrAudioBean b = DataHelper
										.getImageOrAudioBeanInfoByPath(
												mAppContext, filePath, 1);
								b.setParentId(String.valueOf(bean.getId()));
								b.setSponsorType(mRegisterType);
								if (mRegisterType.equals(DataConfig.REGISTER_TYPE_2)
										|| mRegisterType.equals(DataConfig.REGISTER_TYPE_3)) {
									b.setServiceId(2);
								}else {
									b.setServiceId(3);
								}
								b.setSponsorId(bean.getEduComld());
								b.setImie(mAppContext.getImei());
								mKjdb.save(b);
								//TODO 更新视图
								mHandler.sendEmptyMessage(MSG_LOAD_DATA);
								mListView.setSelection(0);
								mAdapter.notifyDataSetChanged();
							}
						}
					}
				}
			}).run();
		}
	}

	@Override
	protected void onStop() {
		super.onStop();
		if (mLogic != null) {
			mLogic.destory();
		}
		MtRfid.getInstance().RfidClose(); // Close
		// FingerprintManager.getInstance().closeSerialPort();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (KeyEvent.KEYCODE_BACK == keyCode) {
			if (mExpandShow) {
				shrinkRecordList();
				return true;
			} else {
				// FingerprintManager.getInstance().closeSerialPort();
				if (mLogic != null) {
					mLogic.destory();
				}
				finish();
			}
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		if (mRecorder == null)
			return;
		if (mRecorder.sampleLength() == 0)
			return;

		Bundle recorderState = new Bundle();

		mRecorder.saveState(recorderState);
		recorderState.putBoolean(SAMPLE_INTERRUPTED_KEY, mSampleInterrupted);
		recorderState.putLong(MAX_FILE_SIZE_KEY, mMaxFileSize);

		outState.putBundle(RECORDER_STATE_KEY, recorderState);
	}

	@Override
	protected void onDestroy() {
		mHandler.removeCallbacks(mUpdateTimer);
		if (mRecorder != null) {
			mRecorder.removeOnStateChangedListener(this);
		}
		unbindService(mServiceConnection);
		if (mService.getRecordState() == SoundRecorder.STATE_IDLE) {
			stopService(new Intent(this, SoundRecorderService.class));
		}
		super.onDestroy();
	}

	@Override
	public void onStateChanged(int state) {
		if (state == SoundRecorder.STATE_STOP_RECORDING) {
			updateUi();
			showSaveRecordDialog();
		}
	}

	@Override
	public void onError(int error) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onPositive() {
		if (saveSample()) {
			mSoundRecord.setEnabled(false);
			updateUi();
	    }
	}

	@Override
	public void onNegative() {
		mSoundRecord.setEnabled(true);
		mLastFileName = null;
		updateUi();
	}
}
